package middleware

import (
	"github.com/gin-gonic/gin"
	"go-programming-tour-book/blog_service/pkg/app"
	"go-programming-tour-book/blog_service/pkg/errcode"
	"go-programming-tour-book/blog_service/pkg/limiter"
)

// RateLimiter 入参应该为 LiniterIface 接口类型。
// 这样，只要符合该接口类型的具体限流器实现都可以传入并使用。
func RateLimiter(l limiter.LimiterIface) gin.HandlerFunc {
	return func(context *gin.Context) {
		key := l.Key(context)
		if bucket, ok := l.GetBucket(key); ok {
			//TakeAvailable 会占用存储桶中立即可用的令牌的数量，返回值为删除的令牌数
			count := bucket.TakeAvailable(1)
			//如果没有可用的令牌，则返回 0，即已经超出配额了。这是将返回 errcode.TooManyRequests 状态，让客户端减缓请求速度
			if count == 0 {
				response := app.NewResponse(context)
				response.ToErrorResponse(errcode.TooManyRequests)
				context.Abort()
				return
			}
		}

		context.Next()
	}
}
